"""ConfigMap资源Markdown写入器模块"""

from typing import Dict, Any, List
import base64
import json
import yaml
from src.writers.base import Writer
from src.utils.markdown_builder import MarkdownBuilder

class ConfigMapWriter(Writer):
    """
    ConfigMap资源Markdown写入器
    负责将提取的ConfigMap资源信息写入Markdown文件
    """
    
    def write(self, data: Dict[str, Any], output_path: str) -> None:
        """
        将提取的ConfigMap信息写入Markdown
        
        Args:
            data: 提取的ConfigMap信息
            output_path: 输出文件路径
        """
        if not data or data.get("kind") != "ConfigMap":
            self.logger.warning(f"无效的ConfigMap数据: {data.get('name', '未知')}")
            return
        
        # 创建Markdown构建器
        md = self.create_markdown_builder()
        
        # 收集节标题，用于生成目录
        sections = ["基本信息", "配置数据"]
        if data.get("binary_data"):
            sections.append("二进制数据")
            
        # 标题
        md.header(f"ConfigMap: {data.get('name', '未知')}", 1)
        
        # 命名空间
        md.bold("命名空间:").text(f" {data.get('namespace', 'default')}").newline(2)
        
        # 目录
        if len(sections) > 2:  # 只有当节较多时才添加目录
            md.toc(sections)
        
        # 基本信息
        md.header("基本信息", 2)
        
        # 基本元数据表
        basic_info = {
            "名称": data.get("name", ""),
            "命名空间": data.get("namespace", "default"),
            "创建时间": data.get("creation_timestamp", ""),
            "数据项数量": len(data.get("data", {}))
        }
        md.dict_table(basic_info)
        
        # 标签和注解
        if data.get("labels"):
            md.header("标签", 3)
            md.dict_table(data.get("labels", {}))
        
        if data.get("annotations"):
            md.header("注解", 3)
            md.dict_table(data.get("annotations", {}))
        
        # 配置数据
        md.header("配置数据", 2)
        
        config_data = data.get("data", {})
        if config_data:
            self._write_config_data(md, config_data)
        else:
            md.paragraph("无配置数据")
        
        # 二进制数据
        binary_data = data.get("binary_data", {})
        if binary_data:
            md.header("二进制数据", 2)
            self._write_binary_data(md, binary_data)
        
        # 生成Markdown文件
        self.write_markdown(md, output_path)
    
    def _write_config_data(self, md: MarkdownBuilder, config_data: Dict[str, Any]) -> None:
        """
        写入配置数据
        
        Args:
            md: Markdown构建器
            config_data: 配置数据字典
        """
        # 配置数据项数信息
        md.paragraph(f"共有 **{len(config_data)}** 项配置数据")
        
        # 遍历每个配置项
        for key, value in config_data.items():
            md.header(f"配置项: {key}", 3)
            
            # 尝试检测数据类型并格式化
            data_type, formatted_value = self._detect_and_format_data(value)
            
            if data_type:
                md.paragraph(f"**数据类型:** {data_type}")
                
                # 根据检测到的类型使用适当的代码块
                with md.code_block(data_type.lower()):
                    md.text(formatted_value)
            else:
                # 如果无法检测类型或是普通文本，直接显示
                if len(value) > 100:  # 长文本使用代码块
                    with md.code_block():
                        md.text(value)
                else:
                    md.paragraph(value)
    
    def _write_binary_data(self, md: MarkdownBuilder, binary_data: Dict[str, Any]) -> None:
        """
        写入二进制数据信息
        
        Args:
            md: Markdown构建器
            binary_data: 二进制数据字典
        """
        md.paragraph(f"共有 **{len(binary_data)}** 项二进制数据")
        
        # 创建二进制数据项表格
        headers = ["数据项名称", "大小", "类型"]
        rows = []
        
        for key, value in binary_data.items():
            try:
                # 如果已经是字符串表示的二进制数据
                size = len(value)
                data_type = self._guess_file_type(key)
                rows.append([key, f"{size} 字节", data_type])
            except Exception as e:
                rows.append([key, "未知", "未知"])
        
        md.table(headers, rows)
    
    def _detect_and_format_data(self, value: str) -> tuple:
        """
        检测并格式化数据
        
        Args:
            value: 要检测的数据字符串
            
        Returns:
            元组 (数据类型, 格式化后的值)
        """
        # 尝试解析为JSON
        try:
            parsed = json.loads(value)
            # 添加换行符确保JSON内容与代码块结束标记分隔
            return "JSON", json.dumps(parsed, indent=2, ensure_ascii=False) + "\n"
        except json.JSONDecodeError:
            pass
        
        # 尝试解析为YAML
        try:
            parsed = yaml.safe_load(value)
            if isinstance(parsed, (dict, list)) and parsed:  # 确保解析结果不是标量或空
                # 添加换行符确保YAML内容与代码块结束标记分隔
                return "YAML", yaml.dump(parsed, default_flow_style=False) + "\n"
        except yaml.YAMLError:
            pass
        
        # 尝试解析为XML
        if value.strip().startswith("<") and value.strip().endswith(">"):
            import re
            if re.search(r"<[^>]+>", value):
                # 确保XML内容末尾有换行符
                if not value.endswith("\n"):
                    value += "\n"
                return "XML", value
        
        # 检查是否为环境变量格式
        env_var_pattern = True
        for line in value.splitlines():
            line = line.strip()
            if line and not line.startswith("#") and "=" not in line:
                env_var_pattern = False
                break
        
        if env_var_pattern and "\n" in value:
            # 确保环境变量内容末尾有换行符
            if not value.endswith("\n"):
                value += "\n"
            return "ENV", value
        
        # 如果是较长的多行文本，标记为TEXT
        if "\n" in value and len(value) > 50:
            # 确保文本内容末尾有换行符
            if not value.endswith("\n"):
                value += "\n"
            return "TEXT", value
        
        # 没有明确的类型，返回空
        return "", value
    
    def _guess_file_type(self, filename: str) -> str:
        """
        根据文件名猜测文件类型
        
        Args:
            filename: 文件名
            
        Returns:
            文件类型字符串
        """
        # 文件扩展名映射到类型
        extension_map = {
            ".json": "JSON文件",
            ".yaml": "YAML文件",
            ".yml": "YAML文件",
            ".xml": "XML文件",
            ".conf": "配置文件",
            ".properties": "属性文件",
            ".txt": "文本文件",
            ".sh": "Shell脚本",
            ".bat": "批处理脚本",
            ".js": "JavaScript",
            ".py": "Python脚本",
            ".crt": "证书文件",
            ".key": "密钥文件",
            ".pem": "PEM文件",
            ".env": "环境变量文件"
        }
        
        # 查找最后一个点后面的内容作为扩展名
        extension = ""
        if "." in filename:
            extension = "." + filename.split(".")[-1].lower()
        
        return extension_map.get(extension, "二进制数据")